home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
MOUSPP30.ARJ
/
MOUSE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-21
|
11KB
|
462 lines
/* -------------------------------------------------------------------- */
/* Mouse++ Version 3.0 mouse.cpp Revised 02/21/92 */
/* */
/* General mouse class for Turbo C++/Borland C++. */
/* Copyright 1991, 1992 by Carl W. Moreland */
/* This source code may be freely distributed as long as the copyright */
/* notice remains intact. */
/* -------------------------------------------------------------------- */
#include <dos.h>
#include "mouse.h"
union REGS reg;
struct SREGS sreg;
Mouse mouse;
struct time t;
unsigned char Mouse::exists = 0;
unsigned char Mouse::enabled = 0;
unsigned char Mouse::visible = 0;
unsigned char Mouse::buttons = 0;
unsigned char Mouse::button = 0;
int Mouse::x = 0;
int Mouse::y = 0;
int Mouse::xcount = 0;
int Mouse::ycount = 0;
unsigned char Mouse::hotx = 0;
unsigned char Mouse::hoty = 0;
int Mouse::oldeventmask = 0;
int Mouse::oldeventseg = 0;
int Mouse::oldeventoff = 0;
unsigned Mouse::clickThreshold = 250;
unsigned char Mouse::handlerInstalled = 0;
unsigned char Mouse::HeadPtr = 0;
unsigned char Mouse::TailPtr = 0;
unsigned char Mouse::event = 0x00;
/* -------------------------------------------------------------------- */
Mouse::Mouse(void) // reset mouse - constructor
{
int found;
_AX = 0x00;
geninterrupt(0x33);
found = _AX;
buttons = _BX;
visible = 0;
if(found)
exists = 1;
if(!exists) return;
_ES = 0;
_DX = 0;
_CX = 0; // clear the event handler
_AX = 0x14;
geninterrupt(0x33);
oldeventmask = _CX; // save the old event handler
oldeventoff = _DX;
oldeventseg = _ES;
_AX = 0x24; // get the mouse info
geninterrupt(0x33);
Info.majorvers = _BH;
Info.minorvers = _BL;
Info.type = _CH;
Info.irq = _CL;
}
Mouse::~Mouse(void) // restore mouse - destructor
{
if(!exists) return;
_AX = 0x00; // reset mouse
geninterrupt(0x33);
if(oldeventmask) // restore old event handler
{
_ES = oldeventseg;
_DX = oldeventoff;
_CX = oldeventmask;
_AX = 0x14;
geninterrupt(0x33);
}
}
void Mouse::Enable(void) // enable the mouse
{
if(!exists || enabled) return;
if(eventMask && !handlerInstalled) // re-install event handler
{
InstallHandler(eventMask, eventHandler);
handlerInstalled = 1;
}
enabled = 1;
}
void Mouse::Disable(void) // disable the mouse
{
if(!exists || !enabled) return;
if(handlerInstalled)
{
ClearHandler(); // disable the event handler
ClearClick(LEFTBUTTON);
ClearClick(RIGHTBUTTON); // clear the multi-click buffers
ClearClick(CENTERBUTTON);
}
Hide(); // turn the cursor off
enabled = 0;
}
void Mouse::Show() // show mouse cursor
{
if(!exists || !enabled) return;
_AX = 0x01;
geninterrupt(0x33);
if(visible < 1) visible++; // visible should now be 1
}
void Mouse::Hide(void) // hide mouse cursor
{
if(!exists || !enabled) return;
if(visible < 1) return;
_AX = 0x02;
geninterrupt(0x33);
visible--; // visible should now be 0
}
void Mouse::Move(int x, int y) // move cursor to col, row
{ // col & row are pixel coordinates
if(!exists || !enabled) return;
_DX = y;
_CX = x;
_AX = 0x04;
geninterrupt(0x33);
}
void Mouse::xLimit(int min, int max) // set min/max column range
{ // min & max are pixel coordinates
if(!exists) return;
_DX = max;
_CX = min;
_AX = 0x07;
geninterrupt(0x33);
}
void Mouse::yLimit(int min, int max) // set min/max row range
{ // min & max are pixel coordinates
if(!exists) return;
_DX = max;
_CX = min;
_AX = 0x08;
geninterrupt(0x33);
}
void Mouse::MickToPix(int horiz, int vert)
{ // set the mickey to pixel ratio
if(!exists) return;
_DX = vert;
_CX = horiz;
_AX = 0x0F;
geninterrupt(0x33);
}
void Mouse::SetSpeedThreshold(unsigned speed)
{ // set speed change threshold
if(!exists) return;
_DX = speed;
_AX = 0x13;
geninterrupt(0x33);
}
void Mouse::SetGraphicsCursor(GraphicsCursor& cursor)
{ // change the graphics cursor
if(!exists) return;
_ES = FP_SEG(cursor.image);
_DX = FP_OFF(cursor.image);
_CX = cursor.hoty;
_BX = cursor.hotx;
_AX = 0x09;
geninterrupt(0x33);
hotx = cursor.hotx;
hoty = cursor.hoty;
}
void Mouse::SetTextCursor(TextCursor& cursor)
{ // change the text cursor
if(!exists) return;
_DX = cursor.arg2;
_CX = cursor.arg1;
_BX = cursor.type;
_AX = 0x0A;
geninterrupt(0x33);
hotx = 0;
hoty = 0;
}
void Mouse::Position(void) // update cursor position &
{ // button status
if(!exists || !enabled) return;
_AX = 0x03;
geninterrupt(0x33);
button = _BX;
x = _CX;
y = _DX;
}
int Mouse::Pressed(int mbutton) // check press status of button
{
if(!exists || !enabled) return(0);
if(handlerInstalled)
{
if(mbutton == LEFTBUTTON)
return(event & LB_PRESSED);
else if(mbutton == RIGHTBUTTON)
return(event & RB_PRESSED);
else if(mbutton == CENTERBUTTON)
return(event & CB_PRESSED);
}
_BX = mbutton;
_AX = 0x05;
geninterrupt(0x33);
button = _AX;
int BX = _BX;
if(BX)
{
x = _CX;
y = _DX;
}
return(BX);
}
int Mouse::Released(int mbutton) // check release status of button
{
if(!exists || !enabled) return(0);
if(handlerInstalled)
{
if(mbutton == LEFTBUTTON)
return(event & LB_RELEASED);
else if(mbutton == RIGHTBUTTON)
return(event & RB_RELEASED);
else if(mbutton == CENTERBUTTON)
return(event & CB_RELEASED);
}
_AX = 0x06;
_BX = mbutton;
geninterrupt(0x33);
button = _AX;
int BX = _BX;
if(BX)
{
x = _CX;
y = _DX;
}
return(BX);
}
void Mouse::Motion(void) // get # of mickeys moved
{
if(!exists || !enabled) return;
_AX = 0x0B;
geninterrupt(0x33);
xcount = _CX;
ycount = _DX;
}
int Mouse::InBox(int left, int top, int right, int bottom)
{ // see if mouse is in a box
if(!exists || !enabled) return(0);
if((x>=left) && (y>=top) && (x<=right) && (y<=bottom))
return(1);
return(0);
}
void Mouse::Exclude(int left, int top, int right, int bottom)
{ // set up exclusion area
if(!exists || !enabled) return;
if((x >= (left-15+hotx)) && (y >= (top-15+hoty)) &&
(x <= (right+hotx)) && (y <= (bottom+hoty)))
Hide();
else
Show();
}
void Mouse::SetClickThreshold(unsigned time)
{
clickThreshold = time; // time is in milliseconds
}
int Mouse::MultiClick(int mbutton) // check for multiple clicks
{
if(!exists || !enabled) return(0);
return Click[mbutton].count;
}
int Mouse::DoubleClick(int mbutton) // check for double clicks
{
if(!exists || !enabled) return(0);
return (Click[mbutton].count == 2);
}
void Mouse::ClearClick(int mbutton) // clear the MultiClick buffer
{
if(!exists || !enabled) return;
Click[mbutton].count = 0;
}
/* ----- Event Driver routines ---------------------------------------- */
void Mouse::InstallHandler(unsigned mask, void interrupt (*handler)(void))
{
if(!exists) return; // set up an event handler
_ES = FP_SEG(handler);
_DX = FP_OFF(handler);
_CX = mask;
_AX = 0x14;
geninterrupt(0x33);
handlerInstalled = 1;
HeadPtr = 0;
TailPtr = 0;
eventMask = mask;
eventHandler = handler;
}
void Mouse::ClearHandler(void) // clear the event handler
{
if(!exists) return;
_ES = 0;
_DX = 0;
_CX = 0;
_AX = 0x14;
geninterrupt(0x33);
handlerInstalled = 0;
HeadPtr = 0;
TailPtr = 0;
}
/* Mouse::Save - stuff the event info in the event buffer */
void Mouse::Save(int event, int button, int x, int y, int xcount, int ycount)
{
unsigned char keymask;
long time;
if((HeadPtr == TailPtr-1) || // see if the buffer is full
(HeadPtr == MOUSE_BUFFER_SIZE-1 && TailPtr == 0))
return;
if((event & LB_PRESSED) || (event & RB_PRESSED) || (event & CB_PRESSED))
{
gettime(&t); // get the event time
time = (long)t.ti_hour*3600000L + // convert to milliseconds
(long)t.ti_min*60000L +
(long)t.ti_sec*1000L +
(long)t.ti_hund*10L;
_AH = 0x02;
geninterrupt(0x16); // get the keyshift mask
keymask = _AL;
button += keymask << 4; // add it to the button mask
if(keymask & 0x03)
button += 0x08;
}
else
time = 0; // no button press so time not needed
Buffer[HeadPtr].event = event; // store the info in the event buffer
Buffer[HeadPtr].button = button;
Buffer[HeadPtr].x = x;
Buffer[HeadPtr].y = y;
Buffer[HeadPtr].xcount = xcount;
Buffer[HeadPtr].ycount = ycount;
Buffer[HeadPtr].time = time;
if(++HeadPtr >= MOUSE_BUFFER_SIZE) // increment the head ptr
HeadPtr = 0;
}
void interrupt MouseHandler(void) // default event handler
{
mouse.Save(_AX,_BX,_CX,_DX,_DI,_SI); // save the normal stuff
EventExit(); // required for interrupt function
}
/* Mouse::GetEvent - read the event buffer and put info into the class */
void Mouse::GetEvent(void)
{
if(!exists || !enabled) return;
int mbutton;
if(HeadPtr != TailPtr)
{
event = Buffer[TailPtr].event;
button = Buffer[TailPtr].button;
x = Buffer[TailPtr].x;
y = Buffer[TailPtr].y;
xcount = Buffer[TailPtr].xcount;
ycount = Buffer[TailPtr].ycount;
if(Buffer[TailPtr].time) // store info for MultiClick()
{
if(event & LB_PRESSED)
mbutton = LEFTBUTTON;
else if(event & RB_PRESSED)
mbutton = RIGHTBUTTON;
else if(event & CB_PRESSED)
mbutton = CENTERBUTTON;
if((Buffer[TailPtr].time - Click[mbutton].time) < clickThreshold)
Click[mbutton].count++;
else
Click[mbutton].count = 1;
Click[mbutton].time = Buffer[TailPtr].time;
}
if(++TailPtr >= MOUSE_BUFFER_SIZE)
TailPtr = 0;
}
else
{
event = 0;
xcount = 0;
ycount = 0;
}
}
void Mouse::ClearEvent(void) // clear the current event
{
event = 0;
button = 0;
x = 0;
y = 0;
xcount = 0;
ycount = 0;
}
void Mouse::ClearBuffer(void) // clear the event buffer
{
HeadPtr = 0;
TailPtr = 0;
}